<?php
/**
* 生成栏目树结构
*/
class Model_Tree
{
	/**
	 * 获得指定分类下的子分类的数组
	 *
	 * @access  public
	 * @param   int     $cat_id     分类的ID
	 * @param   int     $selected   当前选中分类的ID
	 * @param   boolean $re_type    返回的类型: 值为真时返回下拉列表,否则返回数组
	 * @param   int     $level      限定返回的级数。为0时返回所有级数
	 * @param   int     $is_show_all 如果为true显示所有分类，如果为false隐藏不可见分类。
	 * @return  mix
	 */
	function makeTree($cat_id = 0, $selected = 0, $re_type = true, $level = 0, $is_show_all = true)
	{
	    static $res = NULL;
	    if ($res === NULL)
	    {
            $_modelCategory = new Model_Tables_Category();
            if($modelid!=0)
            {
            	$res = $_modelCategory->getSameModelCategoryList($modelid); //读取模型相同的栏目列表          
            }
            else
            {
            	$res = $_modelCategory->getCategoryList(); //读取所有栏目列表          
            }  
//            $res2 = $_modelCategory->getCategoryContentNum();//读取栏目内容数列表
//            $newres = array();
//            foreach($res2 as $k=>$v)
//            {
//                $newres[$v['catid']] = $v['contentsnum'];
//            }
//            foreach($res as $k=>$v)
//            {
//                $res[$k]['contentsnum'] = !empty($newres[$v['catid']]) ? $newres[$v['catid']] : 0;
//            }
	    }
	
	    if (empty($res) == true)
	    {
	        return $re_type ? '' : array();
	    }
	
	    $options = $this->cat_options($catid, $res); // 获得指定分类下的子分类的数组
	
	    $children_level = 99999; //大于这个分类的将被删除
	    if ($is_show_all == false)
	    {
	        foreach ($options as $key => $val)
	        {
	            if ($val['level'] > $children_level)
	            {
	                unset($options[$key]);
	            }
	            else
	            {
	                if ($val['ismenu'] == 0)
	                {
	                    unset($options[$key]);
	                    if ($children_level > $val['level'])
	                    {
	                        $children_level = $val['level']; //标记一下，这样子分类也能删除
	                    }
	                }
	                else
	                {
	                    $children_level = 99999; //恢复初始值
	                }
	            }
	        }
	    }
	
	    /* 截取到指定的缩减级别 */
	    if ($level > 0)
	    {
	        if ($catid == 0)
	        {
	            $end_level = $level;
	        }
	        else
	        {
	            $first_item = reset($options); // 获取第一个元素
	            $end_level  = $first_item['level'] + $level;
	        }
	
	        /* 保留level小于end_level的部分 */
	        foreach ($options AS $key => $val)
	        {
	            if ($val['level'] >= $end_level)
	            {
	                unset($options[$key]);
	            }
	        }
	    }
	
	    if ($re_type == true)
	    {
	        $select = '';
	        foreach ($options AS $var)
	        {
	            $select .= '<option value="' . $var['catid'] . '" ';
	            $select .= ($selected == $var['catid']) ? "selected='ture'" : '';
	            $select .= '>';
	            if ($var['level'] > 0)
	            {
	                $select .= str_repeat('&nbsp;', $var['level'] * 4);
	            }
	            $select .= $var['catname'] . '</option>';
	        }
	
	        return $select;
	    }
	    else
	    {
	        foreach ($options AS $key => $value)
	        {
	            $options[$key]['url'] = "#";//build_uri('category', array('cid' => $value['catid']), $value['catname']);
	        }
	
	        return $options;
	    }
	}
	
		
	/**
	 * 过滤和排序所有分类，返回一个带有缩进级别的数组
	 *
	 * @access  private
	 * @param   int     $catid     上级分类ID
	 * @param   array   $arr        含有所有分类的数组
	 * @param   int     $level      级别
	 * @return  void
	 */
	function cat_options($spec_catid, $arr)
	{
	    static $cat_options = array();
	
	    if (isset($cat_options[$spec_catid]))
	    {
	        return $cat_options[$spec_catid];
	    }
	
	    if (!isset($cat_options[0]))
	    {
	        $level = $last_catid = 0;
	        $options = $catid_array = $level_array = array();
	//        $data = NULL;//read_static_cache('cat_option_static');
	//        if ($data === false)
	//        {
	            while (!empty($arr))
	            {
	                foreach ($arr AS $key => $value)
	                {
	                    $catid = $value['catid'];
	                    if ($level == 0 && $last_catid == 0)
	                    {
	                        if ($value['parentid'] > 0)
	                        {
	                            break;
	                        }
	
	                        $options[$catid]          = $value;
	                        $options[$catid]['level'] = $level;
	                        $options[$catid]['id']    = $catid;
	                        $options[$catid]['name']  = $value['catname'];
	                        unset($arr[$key]);
	
	                        if ($value['haschildren'] == 0)
	                        {
	                            continue;
	                        }
	                        $last_catid  = $catid;
	                        $catid_array = array($catid);
	                        $level_array[$last_catid] = ++$level;
	                        continue;
	                    }
	
	                    if ($value['parentid'] == $last_catid)
	                    {
	                        $options[$catid]          = $value;
	                        $options[$catid]['level'] = $level;
	                        $options[$catid]['id']    = $catid;
	                        $options[$catid]['name']  = $value['catname'];
	                        unset($arr[$key]);
	
	                        if ($value['haschildren'] > 0)
	                        {
	                            if (end($catid_array) != $last_catid)
	                            {
	                                $catid_array[] = $last_catid;
	                            }
	                            $last_catid    = $catid;
	                            $catid_array[] = $catid;
	                            $level_array[$last_catid] = ++$level;
	                        }
	                    }
	                    elseif ($value['parentid'] > $last_catid)
	                    {
	                        break;
	                    }
	                }
	
	                $count = count($catid_array);
	                if ($count > 1)
	                {
	                    $last_catid = array_pop($catid_array);
	                }
	                elseif ($count == 1)
	                {
	                    if ($last_catid != end($catid_array))
	                    {
	                        $last_catid = end($catid_array);
	                    }
	                    else
	                    {
	                        $level = 0;
	                        $last_catid = 0;
	                        $catid_array = array();
	                        continue;
	                    }
	                }
	
	                if ($last_catid && isset($level_array[$last_catid]))
	                {
	                    $level = $level_array[$last_catid];
	                }
	                else
	                {
	                    $level = 0;
	                }
	            }
	            //如果数组过大，不采用静态缓存方式
	//            if (count($options) <= 2000)
	//            {
	//                write_static_cache('cat_option_static', $options);
	//            }
	//        }
	//        else
	//        {
	//            $options = $data;
	//        }
	        $cat_options[0] = $options;
	    }
	    else
	    {
	        $options = $cat_options[0];
	    }
	
	    if (!$spec_catid)
	    {
	        return $options;
	    }
	    else
	    {
	        if (empty($options[$spec_catid]))
	        {
	            return array();
	        }
	
	        $spec_catid_level = $options[$spec_catid]['level'];
	
	        foreach ($options AS $key => $value)
	        {
	            if ($key != $spec_catid)
	            {
	                unset($options[$key]);
	            }
	            else
	            {
	                break;
	            }
	        }
	
	        $spec_catid_array = array();
	        foreach ($options AS $key => $value)
	        {
	            if (($spec_catid_level == $value['level'] && $value['catid'] != $spec_catid) ||
	                ($spec_catid_level > $value['level']))
	            {
	                break;
	            }
	            else
	            {
	                $spec_catid_array[$key] = $value;
	            }
	        }
	        $cat_options[$spec_catid] = $spec_catid_array;
	
	        return $spec_catid_array;
	    }
	}
	
}
?>